// main urls
var platformurl;
var gamepadurl;
var manifesturl;
var bugcatcher_url = "http://bugcatcher.swtor.com/bugcatcher/catchme";
var promosUrl=
  { 'en-us':"http://www.swtor.com/launcher"
  , 'de-de':"http://www.swtor.com/de/launcher"
  , 'fr-fr':"http://www.swtor.com/fr/launcher"
  };
var patchNotesUrl=
  { 'en-us':'http://www.swtor.com/patch/latest'
  , 'de-de':'http://www.swtor.com/de/patch/latest'
  , 'fr-fr':'http://www.swtor.com/fr/patch/latest'
  };
// the logged in user
var user = null;
var envFilter = null;
var envs = [];
var loggedIn = true;
var showDevInfo = true;
var canEditComments = true;
var disableLogins = false;
var lastLogin = null;

// selected env
var pickedEnv = null;
var pickedProduct = '';

/////////////////////////////////
var internal_launchpad_url="http://preprodlaunchapp01.bwa.biowareonline.int:8080/launchpad/";
var external_launchpad_url="https://launchpad.swtor.com/launchpad/";

var internal_gamepad_url="preprodlaunchapp01.bwa.biowareonline.int:8080";
var external_gamepad_url="gamepad.swtor.com:8080";

var external_manifest_url = "manifest.swtor.com";
var internal_manifest_url = "patcherdev.bwa.biowareonline.int";
var test2_manifest_url    = "patcherdev2.bwa.biowareonline.int";
var test3_manifest_url    = "patcherdev03.bwa.biowareonline.int";
var test4_manifest_url    = "patcherdev04.bwa.biowareonline.int";
var test5_manifest_url    = "patcherdev05.bwa.biowareonline.int";
//////////////////////////////////

var autoCloseStr = SSN.Launcher.getSetting('autoclose', SSN.Launcher.getConfig('AutoClose', ''))
var disableKillProcStr = SSN.Launcher.getSetting('killkillproc', SSN.Launcher.getConfig('KillKillProc', 'FALSE'))

var allowRestart = false;
var restartTimeoutStarted = false;

function CloseLauncher()
{
    new AjaxLogTransmissionCall().execute();
    SSN.Launcher.close();
}

function setInternalPlatform()
{
    platformurl = SSN.Launcher.getSetting('InternalLaunchpad', SSN.Launcher.getConfig('InternalLaunchpad', internal_launchpad_url));
    gamepadurl = SSN.Launcher.getSetting('InternalGamepad', SSN.Launcher.getConfig('InternalGamepad', internal_gamepad_url));
    $("body").addClass("dev");
    if( $("#platformSelectorProduction .switchButton").is(".hover") ){
        $("#platformSelectorDevelopment .switchButton").addClass("hover");
    }
}

function setExternalPlatform()
{
    platformurl = SSN.Launcher.getSetting('ExternalLaunchpad', SSN.Launcher.getConfig('ExternalLaunchpad', external_launchpad_url));
    gamepadurl = SSN.Launcher.getSetting('ExternalGamepad', SSN.Launcher.getConfig('ExternalGamepad', external_gamepad_url));
    $("body").removeClass("dev");
    if( $("#platformSelectorDevelopment .switchButton").is(".hover") ){
        $("#platformSelectorProduction .switchButton").addClass("hover");
    }
}

setExternalPlatform();

var duration = function(time,animate){ return (animate==null?+time:(animate?+animate:0)); };
var error = function(msg){ 
    $("#error p").text(msg); 
    if((autoCloseStr == "PLAY")||(autoCloseStr == "CLOSE")){
        CloseLauncher();
    }
    return error; 
};
error.warn = function(msg){
    $("#error p").text(msg);
    return error;
};
error.show = function(animate){
  var time = duration(200,animate);
  $("#error").css({opacity:0}).show().stop().animate({opacity:1},time,'ease');
};
error.hide = function(animate){
  var time = duration(200,animate);
  $("#error").stop().animate({opacity:0},time,'ease', function(){ $("#error").hide(); });
};

$.fn.insertHTML = function(html,selector,error){
    html = html.replace(/<body(?: [^>]*?)>/i,'<body>').replace(/<!--(?:.|\r|\n)*?-->/g,'');
    var start = html.indexOf('<body>')
      , end = html.indexOf('</body>');
    if(start<0){ start=-6; }
    start+=6;
    if(end<0){ end=html.length-start; }
    html = html.substr(start,(end-start));
    html = $(html);
    if( selector ){ html=html.find(selector).children(); }
    if( !html.length ){ error(); return this; }
    html = html.filter(function(){ return !$(this).is("script,style") || $(this).is(".launcher"); });
    html.find("script").not(".launcher").remove();
    html.find("style").not(".launcher").remove();
    return this.html( html );
};
function offline(){
    $("#login").addClass("disabled");
    error(strings[lang]["Servers are down for maintenance. Please check back later."]).show();
    log('ERROR','Going Offline');
    $("#login input").attr("disabled","disabled");
}

var content =
{ small: function(animate){
    var time = duration(400,animate);
    $("#logo").animate({opacity:1},time,'ease');
    $("#main").animate({top:212},time,'ease');
    $("#content, #content>*").animate({height:120},{queue:false,duration:time,easing:'ease'});
  }
, medium: function(animate){
    var time = duration(400,animate);
    $("#logo").animate({opacity:1},time,'ease');
    $("#main").animate({top:182},time,'ease');
    $("#content, #content>*").animate({height:240},{queue:false,duration:time,easing:'ease'});
  }
, large: function(animate){
    var time = duration(400,animate);
    $("#logo").animate({opacity:0},time,'ease');
    $("#main").animate({top:62},time,'ease');
    $("#content, #content>*").animate({height:360},{queue:false,duration:time,easing:'ease'});
  }
};

function enableButton(button){
    button = $(button||"#next-Button");
    button.removeClass("disabled");
    button.find(".inactive").stop().animate({opacity:0},200,'ease');
    if( button.is(".hover") ){
      button.find(".on").stop().animate({opacity:1},200,'ease');
    }
}
function disableButton(button){
    button = $(button||"#next-Button");
    button.addClass("disabled");
    button.find(".inactive").stop().animate({opacity:0.8},200,'ease');
}

function enableBackButton(){ enableButton("#back-Button"); }
function disableBackButton(){ disableButton("#back-Button"); }

var loginProgress =
  { show: function(animate){ $("#loginProgress").stop().animate({opacity:1},duration(200,animate),'ease'); }
  , hide: function(animate){ $("#loginProgress").stop().animate({opacity:0},duration(200,animate),'ease'); }
  };

var productSelections =
  { none:    {show:"",hide:"#retail,#clients,#tools"}
  , retail:  {show:"#retail", hide:"#clients,#tools"}
  , clients: {show:"#retail,#clients", hide:"#tools"}
  , tools:   {show:"#retail,#clients,#tools",hide:""}
  };
function productSelect(product){
  product = product || "none";
  $(productSelections[product].hide).hide()
  $(productSelections[product].show).show()
}

var screen =
{ login:
  { show: function(animate){
      var time = duration(200,animate);
      content.small(animate);
      $("#login").css({opacity:0,top:-20}).show().animate({top:0,opacity:1},time,'ease');
      $("#loginButton").show();
    }
  , hide: function(animate){
      var time = duration(200,animate);
      $("#login").animate({top:20,opacity:0},time,'ease',function(){ $("#login").hide(); });
      $("#loginButton").hide();
    }
  }
, captcha:
  { show: function(animate){
      var time = duration(400,animate);
      content.medium(animate);
      error(strings[lang]["Multiple failures mean you have to enter a security code."]).show();
      log('INFO','Multiple login failures, captcha Activated');
      //$(".cpimage").show();
      $(".cpaudio").hide();
      $("#captcha").css({opacity:0,height:50}).show().animate({opacity:1},400,'ease');
      $("#captcha").animate({height:130},{queue:false,duration:400,easing:'ease'});
      $("#login input[name=password]")[0].focus();
    }
  , hide: function(animate){
      var time = duration(400,animate);
      error.hide();
      $("#captcha").animate({opacity:0,height:50},time,'ease',function(){ $("#captcha").hide(); });
    }
  }
, tos:
  { show: function(animate){
      var time = duration(200,animate);
      content.medium(animate);
      $("#nextButton").show();
      $("#content>.help").css({opacity:0}).show().animate({opacity:1},time,'ease');
      $("#tos").css({opacity:0,top:-20}).show().animate({top:0,opacity:1},time,'ease');
      $("#agreement").css({opacity:0}).show().animate({opacity:1},time,'ease');
      //$("#terms").scrollbar();
    }
  , hide: function(animate){
      var time = duration(200,animate);
      $("#nextButton").hide();
      $("#tos").animate({top:20,opacity:0},time,'ease',function(){ $("#tos").hide(); });
      $("#agreement").animate({opacity:0},time,'ease',function(){ $("#agreement").hide(); });
    }
  }
, environments:
  { show: function(animate){
      var time = duration(200,animate);
      if( $("body").is(".dev") ){ content.large(animate); }
      else{ content.medium(animate); }
      $("#nextButton").show();
      $("#environments").css({opacity:0,top:-20}).show().animate({top:0,opacity:1},time,'ease');
    }
  , hide: function(animate){
      var time = duration(200,animate);
      $("#nextButton").hide();
      $("#environments").animate({top:20,opacity:0},time,'ease',function(){ $("#environments").hide(); });
    }
  }
, patching:
  { show:function(animate){
      var fast = duration(200,animate);
      content.medium(animate);
      $("#pauseButton").show();
      $("#patching").css({opacity:0,top:-20}).show().animate({top:0,opacity:1},fast,'ease');
      $("#patchNotes").scrollbar();
      screen.patching.showProgress(animate);
    }
  , hide: function(animate){
      var fast = duration(200,animate);
      $("#updateButton, #pauseButton, #nextButton, #resumeButton").hide();
      $("#patching").animate({top:20,opacity:0},fast,'ease',function(){ $("#patching").hide(); });
      $("#content>.help").css({opacity:1}).animate({opacity:0},fast,'ease');
      screen.patching.hideProgress(animate);
    }
  , showProgress:function(animate){
      var time = duration(400,animate);
      $("#progress").show();
      $("#progressHelp").css({opacity:0}).animate({opacity:1},time,'ease');
      $("#progressArea").css({top:40}).animate({top:0},time,'ease');
    }
  , hideProgress:function(animate){
      var time = duration(400,animate);
      $("#progress:visible #progressHelp").animate({opacity:0},time,'ease');
      $("#progress:visible #progressArea").animate({top:40},time,'ease',function(){ $("#progress").hide(); });
    }
  }
, promos:
  { show: function(animate){
      var time = duration(400,animate);
      content.medium(animate);
      enableButton();
      //$("#characterSelect").css({opacity:0}).show().animate({opacity:1},200,'ease');
      $("#playButton").show();
      $("#promos").css({opacity:0,top:40}).show().animate({top:0,opacity:1},time,'ease');
    }
  , hide: function(animate){
      var time = duration(400,animate);
      $("#playButton").hide();
      $("#promos").animate({top:40,opacity:0},time,'ease',function(){ $("#promos").hide(); });
    }
  }
, restarting:
  { show: function(animate){
      var time = duration(400,animate);
      var fast = duration(200,animate);
      $("input").each(function(){ this.blur(); });
      $("#overlay").css({opacity:0}).show().animate({opacity:0.7},time,'ease').unbind("click");
      $("#restarting").css({opacity:0}).show().animate({opacity:1},fast,'ease');
    }
  , hide: function(animate){
      var time = duration(200,animate);
      $("#overlay, #restarting").animate({opacity:0},time,'ease',function(){ $(this).hide(); });
      getLauncherSettings();
    }
  }
, ppatching:
  { show: function(animate){
      var time = duration(400,animate);
      var fast = duration(200,animate);
      $("input").each(function(){ this.blur(); });
      $("#overlay").css({opacity:0}).show().animate({opacity:0.7},time,'ease').unbind("click");
      $("#ppatching").css({opacity:0}).show().animate({opacity:1},fast,'ease');
    }
  , hide: function(animate){
      var time = duration(200,animate);
      $("#overlay, #ppatching").animate({opacity:0},time,'ease',function(){ $(this).hide(); });
      getLauncherSettings();
    }
  }
, pchecking:
	{ show: function(animate){
	    var time = duration(400,animate);
	    var fast = duration(200,animate);
	    $("input").each(function(){ this.blur(); });
	    $("#overlay").css({opacity:0}).show().animate({opacity:0.7},time,'ease').unbind("click");
	    $("#pchecking").css({opacity:0}).show().animate({opacity:1},fast,'ease');
	  }
	, hide: function(animate){
	    var time = duration(200,animate);
	    $("#overlay, #pchecking").animate({opacity:0},time,'ease',function(){ $(this).hide(); });
	    getLauncherSettings();
	  }
	}
};

function playButton(){
  $("#explosion").show().animate({ opacity:0, width:160, height:60, left:694, top:442 },400,'ease');
  $("#next-Button").removeClass("hover").find(".on").stop().animate({opacity:0},200,'ease');
}

function glowProgress(){
  var w = $("#progressbarFilled").width();
  if(w == $("#progressbarFilled").parent().width()){ return } //finished downloading
  $("#progressbarFilled .glow").stop().css({left:w}).animate({left:-270},6000,'linear');
}
function buildEnvironments(envs) 
{
  var section = $('<div class="section">').html(strings[lang]['All environments']+' (<b>'+envs.length+'</b>)');
  $("#envList").scrollbar(false).empty().append( section );
  var list = $([]);
  for(var e=0;e<envs.length;e++)
  {
      var env = envs[e];
      if(envFilter){
        var reg = new RegExp(envFilter,'i');
        if( !reg.test(env.displayName) && !reg.test(env.name) ){ continue; }
      }
      var extraClasses='';
      if(!env.isOnline){ extraClasses=' down'; }
      var environment = $('<div class="environment">').addClass(e%2?"odd":"even").data("environment",env);
      var firstline = $('<div>').appendTo(environment);
      $('<div class="title'+extraClasses+'">').html(env.displayName).appendTo(firstline);
      if( env.name != env.displayName ){ $('<div class="name">').text('('+env.name+')').appendTo(firstline); }
      var comment = env.comment;
      if(comment){
        environment.addClass("commented")
        $('<div class="comment">').html(comment).appendTo(environment);
      }
      if(env.toolsOk){
        environment.addClass("detailed")
        var info = $('<div class="info">');
        if(env.buildTag){
            info.append( $('<span class="branch"></span>').text(env.buildTag.replace(/^\s*shard:\s*/i,'')) );
        }
        if((env.population != null)&&(env.population != undefined)){
            info.append( $('<span class="users"></span>').text('('+env.population+" user"+(env.population==1?"":"s")+")") );
        }
        firstline.append(info);
      }
      if(!env.isOnline){ environment.addClass("offline"); }
      environment.wrapInner('<div class="inner">');
      $("#envList").append(environment);
  }
  $("#envList").scrollbar();
}

function showEnvironmentsPageIfNecessary()
{
    var enviro = SSN.Launcher.getSetting('RestartEnvironment');
    var prodo = SSN.Launcher.getSetting('RestartProduct');
    if((enviro != null)&&(enviro != undefined)&&(enviro != 'undefined')&&(enviro.length > 0))
    {
        SSN.Launcher.setSetting('RestartEnvironment','');
        SSN.Launcher.setSetting('RestartProduct','');
        SSN.Launcher.saveSettings();
    }
    else
    {
        enviro = SSN.Launcher.getSetting('LastEnvironment');
        prodo = SSN.Launcher.getSetting('LastProduct');
        if((enviro == null)||(enviro == undefined)||(enviro == 'undefined')||(enviro.length==0))
        {
            if((envs.length==1)
            &&(!envs[0].toolsOk)
            &&(!envs[0].allClientsOk))
            {
                enviro = envs[0].name;
                prodo='retailclient';
            }
        }
    }
    
    if((enviro != null) && (enviro!=undefined) && (enviro!='undefined') && (enviro.length>0))
    {
        var enviroName=enviro;
        enviro=null;
        for(var i=0;i<envs.length;i++)
        {
            if(envs[i].name == enviroName)
                enviro=envs[i];
        }
    }
    /*
    if((enviro != null) && (prodo != null) 
    && (enviro != undefined) && (prodo != undefined) 
    && (enviro != 'undefined') && (prodo != 'undefined') 
    &&(prodo.length>0))
    {
		*/
        error.hide();
        screen.patching.show();
        log('INFO','Auto patch is starting...');
				log('INFO','ENVIRO: ' + enviro);
				log('INFO','PRODO: ' + prodo);
        new AjaxGetPatchNotes().execute(enviro);
        startPatch(enviro,prodo);
    /*
		}
    else
    {
        disableButton();
        screen.environments.show();
    }
		*/
}

function patchNextClicked()
{
    var environment = $(".environment.active");
    var product = $(".product.active");
    if(!environment.length || !product.length)
    {
        log('ERROR','Faulty environment'+environment.length+'/product'+product.length+' found. ABORT!');
        return; 
    }
    environment = environment.data("environment");
    product = product.data("product");
    startPatch(environment, product);
}

function getLauncherSettings()
{
    var autoEnv = (SSN.Launcher.getSetting('EnableAutoEnvironment', 'false').toLowerCase() == 'true');
    var maxUploadRate = SSN.Launcher.getSetting('uploadRate', '0');
    var maxDownloadRate = SSN.Launcher.getSetting('downloadRate', '0')
    var rateLimit = !!( +maxUploadRate + +maxDownloadRate );
    lang = SSN.Launcher.getSetting('language', SSN.Launcher.getConfig('Language', 'en-us'));
    $('#enableAutoProduct').attr('checked', autoEnv ? 'checked' : '').change();
    $('#languageDropDown').val(lang).change();
    $('#maxUploadRate').val(maxUploadRate).change();
    $('#maxDownloadRate').val(maxDownloadRate).change();
    //SSN.Launcher.setSettings(enableP2P,true,rateLimit,maxUploadRate,maxDownloadRate);
}

function submitNewSettings()
{
    var autoEnv = $('#enableAutoProduct').is(":checked");
    var maxUploadRate = $('#maxUploadRate').val();
    var maxDownloadRate = $('#maxDownloadRate').val();
    var rateLimit = !!( +maxUploadRate + +maxDownloadRate );
    lang = $('#languageDropDown').val() || 'en-us';
    translate();
    $(document).trigger("language");
    var enviro = SSN.Launcher.getSetting('LastEnvironment');
    var prodo = SSN.Launcher.getSetting('LastProduct');

    SSN.Launcher.setSetting('loglevels', logLevelsStr);
    //SSN.Launcher.setSetting('HTTPEnabled', enableWeb);
    SSN.Launcher.setSetting('enableRateLimit', rateLimit);
    SSN.Launcher.setSetting('uploadRate', maxUploadRate);
    SSN.Launcher.setSetting('downloadRate', maxDownloadRate);
    
    SSN.Launcher.setSetting('language', lang);
    SSN.Launcher.setSetting('EnableAutoEnvironment', autoEnv);
    if(!autoEnv)
    {
        SSN.Launcher.setSetting('LastEnvironment', '')
        SSN.Launcher.setSetting('LastProduct', '')
    }
    //SSN.Launcher.setSettings(enableP2P,true,rateLimit,maxUploadRate,maxDownloadRate);
    SSN.Launcher.saveSettings();
    updateDownloadSettings();
    changeLangPackageList(prevLang);
    prevLang=lang;
}

function startEditShardComment(obj,env,xtra)
{
    var oldComment = env.comment;
    var comment = env.comment;
    while(true)
    {
        var newComment = window.prompt(xtra+'Enter new comment',comment);
        if((newComment == null)||(newComment == comment))
            return;
        comment = newComment;
        if(newComment.length > 80)
            alert('Shard comments can not exceed 80 characters.  Yours was '+newComment.length+'.  Fix it!');
        else
        {
            env.comment = newComment;
            var commentArea = obj.find(".comment");
            commentArea.html( env.comment );
            if((!loggedIn)||(lastLogin==null)||(lastLogin==undefined)||(user==null)||(user==undefined))
            {
                log('ERROR','Error, comment without user!');
                logout();
                return;
            }
            var passBack = new Array();
            passBack[0]=obj;
            passBack[1]=env;
            new AjaxUpdateCommentCall().execute(env.name, user.token, newComment,passBack);  
            return;
        }
    }
}

function refreshEnvironmentsFailed(){ $("#refreshEnv").removeClass("loading"); }
function refreshEnvironmentsComplete(repickedEnv)
{
    $("#refreshEnv").removeClass("loading");
    // yes, we have a repickedEnv (if there is one), but don't use it.. if i 
    // can't restore the scrollbar, whats the point in pretending nothings happened? 
    pickedEnv = null;
    pickedProduct = '';
    $(".environment").removeClass("active");
    $("#products .active").removeClass("active");
    productSelect(false);
    disableButton();
    buildEnvironments(envs);
}

function refreshEnvironments()
{
    $("#refreshEnv").addClass("loading");
    new AjaxRefreshEnvironments().execute("sajt",refreshEnvironmentsComplete,refreshEnvironmentsFailed);
}


function recheckEnvironmentsComplete(recheckedEnv)
{
    $("body").removeClass('waiting');
    pickedEnv=recheckedEnv;
    // only do this if appropriate -- recall the patch-play checks!
    enableButton();
}

// not yet called, but will be called when the marketing/play page is displayed
// this will ensure we *really* know whether to enable the play button
function recheckEnvironments()
{
    $("body").addClass('waiting');
    disableButton();
    new AjaxRefreshEnvironments().execute(user.token,recheckEnvironmentsComplete);
}

function login()
{
    if( disableLogins || ($("#next-Button").is(".disabled")) || $("#environments").is(":visible") ){
        log("ERROR","User is trying to spam login! Stop it!");
        return;
    }
    var login = $("input[name=login]").val();
    var pass = $("input[name=password]").val();
    var remember = $("input[name=remember]").is(":checked");
    if( !login || !pass ){ 
        log("ERROR","No login"+login+"/pass"+pass+" found.  ABORT!");
        return;
    }
    disableLogins=true;
    //TODO: fix disableButton
    disableButton();
    saveLoginValues();
    loginProgress.show();
    $("body").addClass('waiting');
    log("DEBUG","Logging in as "+login);
    SSN.Launcher.saveSettings();
    if($("#captcha").is(":visible"))
    {
        var captcha = $("input[name=captcha]").val();
        new AjaxSingleLogin().execute( login, pass, null );
    }
    else
    {
        new AjaxSingleLogin().execute( login, pass, null );
    }
}

function saveLoginValues()
{
    var login = $("input[name=login]").val();
    var remember = $("input[name=remember]").is(":checked");
    if(remember)
    { 
    	SSN.Launcher.setSetting($("body").is(".dev")?'DevLogin':'Login',login); 
    }
    else 
    { 
    	SSN.Launcher.setSetting($("body").is(".dev")?'DevLogin':'Login',''); 
    }
}

function completeAutoLogin(token, patch_token)
{
    if((autoCloseStr == "PLAY")||(autoCloseStr == "CLOSE"))
    {
	    SSN.Launcher.setSetting('AutoClose','NONE');
    }
    SSN.Launcher.setSetting('RestartGameKey','');
    SSN.Launcher.setSetting('RestartPatchKey','');
    SSN.Launcher.saveSettings();
    new AjaxSingleLogin().executeToken(token, patch_token);
}

function autologin()
{
    var token = SSN.Launcher.getSetting('RestartGameKey');
    if((token != null)&&(token != undefined)&&(token != 'undefined')&&(token != ''))
    {
        $("#login").hide();
        var patch_token = SSN.Launcher.getSetting('RestartPatchKey'); 
        if((patch_token != null)&&(patch_token != undefined)&&(patch_token != 'undefined')&&(patch_token != ''))
        {
            setTimeout('completeAutoLogin("'+token+'","'+patch_token+'");',1);
            return;
        }
    }
	if( !$("#pchecking").is(":visible") )
        screen.pchecking.show();
    setTimeout('patchThePatcher()',1000);
}

function logout()
{
    user = null;
    envFilter = null;
    envs = [];
    loggedIn = false;
    showDevInfo = false;
    canEditComments = false;
    disableLogins = false;
    lastLogin = null;
    pickedEnv = null;
    pickedProduct = '';
    currentDownloadingProductName='Unknown';
    manifesturl=external_manifest_url;
    patchCompleteCallback = null;
    productSelect(false);
    //TODO: shrink login box back to original size
}

function setup()
{
    // Open links in new window
    if( !browser ){
      $("#frame").append( $("#logging") );
      $("a[href]").live("click",function(){
        this.blur();
        SSN.Launcher.navigate( $(this).attr("href"), true );
        return false;
      });
    }

    SSN.Launcher.initialize();
    SSN.Launcher.attachInteropLibrary("ReqChk.dll");
    SSN.Launcher.attachInteropLibrary("TORLog.dll");
    SSN.Launcher.attachInteropLibrary("ProcChk.dll");
    document.SSNLauncher.SSNLauncher_ReturnBool("init_logging","string:launcher_*.log|int:7|")
    log('INFO','----------------------------------------------------------');
    SSN.Launcher.setConstructHttpTargetCallback(httpTargetCallback);
    SSN.Launcher.setLauncherErrorCallback(patchErrorHandler);
    SSN.Launcher.setLauncherLogCallback(memoryLoggingHandler);
    SSN.Patcher.setPackageListStatusCallback(packageListStatusCallback);
    SSN.Patcher.setPackageAllowRestartCallback(packageAllowRestartCallback);
    
    // Act like an application
    $.each( "beforecopy contextmenu copy dragstart select selectstart".split(" "), function(i,e){
        $(document).bind(e,function(ev){
            if( ev.target.nodeName != "INPUT") return false;
        });
    });

    $("a").click(function(){ SSN.Launcher.navigate( $(this).attr("href"), true ); return false; });
    
    // Window Controls
    $("#draggable, #logo, #topBorder, #bottomBorder>*").mousedown( SSN.Launcher.beginMoveWindow );
    $("#minimize").click( SSN.Launcher.minimize );
    $("#close").click( SSN.Launcher.close );
    $("#settingsButton .icon").click( function(){
        $("#overlay").css({opacity:0}).show().animate({opacity:0.7},400,'ease');
        $("#settings").css({opacity:0}).show().animate({opacity:1},200,'ease');
        $("#settingsButton .on .bg").stop().animate({opacity:0},400,'ease-in');
    });
    $("#overlay, #closeSettings, #closeSettingsButton, #closeExit, #exitCancel").click( function(){
        $("#overlay, #settings, #exitConfirmation").animate({opacity:0},200,'ease',function(){ $(this).hide(); });
        getLauncherSettings();
    });
    
    $("#closeSettings, #closeExit")
    .mouseover(function(){ $(this).find(".on").stop().animate({opacity:1},200,'ease'); })
    .mouseout(function(){  $(this).find(".on").stop().animate({opacity:0},200,'ease'); });

    $("#exitButton").click(function(){
        if( $("#progress").is(":visible") ){
          $("#overlay").css({opacity:0}).show().animate({opacity:0.7},400,'ease');
          $("#exitConfirmation").css({opacity:0}).show().animate({opacity:1},200,'ease');
        } else {
          log('INFO','User presses exit -- L8TRS!'); 
          CloseLauncher();
        }
    });
    $("#exitOK").click(function(){
        log('INFO','User confirms exit -- L8TRS!'); 
        CloseLauncher();
    });

    $("#settingsButton .on .icon").mouseover(function(){
        $("#settingsButton .on .bg").stop().animate({opacity:1},200,'ease');
    }).mouseout(function(){
        if( $("#settings").is(":visible") ){ return }
        $("#settingsButton .on .bg").stop().animate({opacity:0},200,'ease');
    });

    $("#saveSettingsButton").click(function(){
        $("#overlay, #settings").animate({opacity:0},200,'ease',function(){ $(this).hide(); });
        submitNewSettings();
    });

    /*
    $(".settingsButtons").mouseover(function(){
        $(this).addClass("hover");
        if( $(this).is(".disabled") ){ return }
        $(this).find(".on").stop().animate({opacity:1},130,'ease');
    }).mouseout(function(){
        $(this).removeClass("hover").find(".on").stop().animate({opacity:0},130,'ease');
    });
    */

    // Pass clicking events from the disabled overlay to the visible button
    $(".mainButtons").each(function(){
        var self = $(this);
        self.find(".inactive").click(function(){
            if( self.is(".disabled") ){ return false; }
            self.find("*:visible").not(".off, .on, .inactive").click();
        });
    });

    // Comment editing
    $(".comment").click(function(){
    }).mouseover(function(){
        $(this).addClass("hover");
    }).mouseout(function(){
        $(this).removeClass("hover");
    });

    // Refresh Environment
    $("#refreshEnv").click(refreshEnvironments);
    
    // Enter key is the new "next" button
    $(document).keypress(function(e){
        if(e.which==13){ //Enter
            if( $("#settings").is(":visible") ){ $("#saveSettingsButton").click(); }
            else if( $("#exitConfirmation").is(":visible") ){ $("#exitOK").click(); }
            else{ $("#next-Button>*:visible").not(".off, .on, .inactive").click(); }
        } else if(e.which==27 || e.which==23 && e.ctrlKey) { //Esc or ctrl-W
            if( $("#settings").is(":visible") ){ $("#cancelButton").click(); }
            else if( $("#exitConfirmation").is(":visible") ){ $("#exitCancel").click(); }
            else{ $("#exitButton").click(); }
        } else if(e.which==6 && e.ctrlKey && $("#environments").is(":visible") && showDevInfo && envs.length>5){ //ctrl-F
            envFilter = window.prompt('Enter an environment name filter','');
            buildEnvironments(envs);
        }
    });

    $("input[name=remember]").click(function(){
    	// this doesn't work, at all.
        saveLoginValues();
        SSN.Launcher.saveSettings();
    });
    $("#loginButton").click( login );
    $("#refreshCaptcha").click( refreshCaptcha );
    $("#toggleImageCaptcha, #toggleAudioCaptcha").click( toggleCaptcha );
    
    $(".environment").live("click",function(){
        var active = $(this).is(".active");
        $(".environment").removeClass("active");
        $("#products .product.active").removeClass("active");
        if(active){ productSelect(false); disableButton(); return; }
        var env = $(this).addClass("active").data("environment");
        new AjaxGetPatchNotes().execute(env);
        if(env.toolsOk){ productSelect("tools"); }
        else if(env.allClientsOk){ productSelect("clients"); }
        else { productSelect("retail"); }
        var products = $("#products .product:visible");
        if(products.length==1){
            products.addClass("active");
            enableButton();
        }else {
            disableButton();
        }
    }).live("dblclick",function(){
        var env = $(this).data("environment");
        if((env != null) && (env != undefined) && (env.editcomments))
        {
            startEditShardComment($(this),env,'');
        }
    });

    $(".product").live("click",function(){
        var active = $(this).is(".active");
        $(".product").removeClass("active");
        if(active){ disableButton(); return; }
        $(this).addClass("active");
        enableButton();
    });

    $(".mainButtons").mouseover(function(){
        $(this).addClass("hover");
        if( $(this).is(".disabled") ){ return }
        $(this).find(".on").stop().animate({opacity:1},200,'ease');
    }).mouseout(function(){
        $(this).removeClass("hover").find(".on").stop().animate({opacity:0},200,'ease');
    });

    $("#frame input, #frame select").inputs();
    $("#frame .checkbox input").hide();
    $("#frame label, #frame .checkbox").unbind("click").click(function(){
        var input = $(this);
        if(input.is("label")){ input = $("input[name="+input.attr("for")+"]"); }
        else { input = input.find("input"); }
        if(!input.length){ return; }
        input.attr("checked",(input.is(":checked")?"":"checked")).change();
        return false;
    });
    
    $("#login").find("input[name=login], input[name=password]").keypress(function(){
      setTimeout(function(){
      var login = $("#login input[name=login]").val();
      var pass = $("#login input[name=password]").val();
      if( login && pass ){ enableButton() }
      else{ disableButton(); }
      },1);
    });
    
    $("#nextButton").click(function(){
        if( $("#next-Button").is(".disabled") ){ return false; }
        var environment = $(".environment.active").length || pickedEnv;
        var product = $(".product.active").length || pickedProduct;
        if( $("#tos").is(":visible") ) {
            log('DEBUG','User clicked TOS NEXT, wants to see environments (or start patching).');
            new AjaxAgreeToTermsCall().execute();
            screen.tos.hide();
            showEnvironmentsPageIfNecessary();
        }
        else if( !environment || !product ){ return false; }
        else if( $("#environments").is(":visible") ){
          log('DEBUG','User clicked NEXT, wants to start patching.');
          patchNextClicked();
          screen.environments.hide();
          screen.patching.show();
        }
        else if( $("#patching").is(":visible") ){
          screen.patching.hide();
          screen.promos.show();
        }
        else log('ERROR','User clicked NEXT, but theres nothing to do!');
    });
    $("#backButton").click(function(){
        if( $("#back-Button").is(".disabled") ){ return false; }
        if( $("#tos").is(":visible") ) {
          screen.tos.hide();
          screen.login.show();
          disableButton();
          disableBackButton();
          logout();
          error.hide();
          $("#login input[name=password]")[0].focus();
        } else if( $("#environments").is(":visible") ){
          screen.environments.hide();
          screen.login.show();
          disableButton();
          disableBackButton();
          logout();
          error.hide();
          $("#login input[name=password]")[0].focus();
        } else if( $("#patching").is(":visible") ){
          screen.patching.hide();
          screen.environments.show();
          error.hide();
          abortCurrentPatch();
        } else if( $("#promos").is(":visible") ){
          screen.promos.hide();
          screen.patching.show();
          error.hide();
        } else { log('ERROR','User clicked NEXT, but theres nothing to do!'); }
    });
    $("#platformSelectorDevelopment .switchButton").click(function(){
        SSN.Launcher.setSetting('LastMode','PROD');
        saveLoginValues();
        SSN.Launcher.saveSettings();
    	setExternalPlatform()
        setLoginName();
    });
    $("#platformSelectorProduction .switchButton").click(function(){
        SSN.Launcher.setSetting('LastMode','DEV');
        saveLoginValues();
        SSN.Launcher.saveSettings();
    	setInternalPlatform()
        setLoginName();
    });
    $("#platformSelector .switchButton")
      .mouseover(function(){ $(this).addClass("hover"); })
      .mouseout(function(){ $(this).removeClass("hover"); });
    $("#updateButton, #resumeButton").click(function(){
        SSN.isPaused = false;
        updateDownloadSettings();
        $("#updateButton, #resumeButton").hide();
        $("#pauseButton").show();
    });
    $("#pauseButton").click(function(){
        SSN.isPaused = true;
        updateDownloadSettings();
        $("#resumeButton").show();
        $("#pauseButton").hide();
    });
    $("#playButton").click(function(){
        playButton();
        disableButton();
        log('DEBUG','User presses Play.  Bye bye now.');
        setTimeout(function(){
          launchProgram();
        },500);
    });
    
    $("#agreement input").change(function(){
        if($("#agreement input").is(":checked"))
        {
            enableButton();
        }
        else
        {
            disableButton();
        }
    });
    
    SSN.defaultGetDownloadName = function()
    {
        return currentDownloadingProductName;
    }
    
    var noPromos = function(){
      $("#promos .content").empty().append( $("#noPromos").clone() );
    };
    var loadedPromos={};
    var loadPromos = function(){
      if(loadedPromos[lang]) {
          $("#promos .content").insertHTML(loadedPromos[lang],'',noPromos);
      } else {
        (function(lang){ //saving lang variable
          $.ajax({url:promosUrl[lang],success:function(html){ //grab the latest promos
              loadedPromos[lang] = html.replace(/>\s+</g,'><'); //remove extra whitespace
              loadPromos();
          },error:noPromos,timeout:10000});
        })(lang);
      }
    };
    $(document).bind("language",loadPromos);
    loadPromos();

    var updateSelect = function(){ $(this).closest(".select").find("li").show().eq(this.selectedIndex||0).hide(); };
    $("#characterSelect select").change(updateSelect).change();

    setInterval(glowProgress,6000);
    getLauncherSettings();
    getSystemSettings();
}

function launcherReady()
{
    autologin();
    setLoginName();
}

function setLoginFocus()
{
    if(!$("#login").is(":hidden"))
    {
        var login = $("input[name=login]").val();
        if(login=='')
        {
            setTimeout(function(){
                $("input[name=login]")[0].focus();
            },10);
        }
        else
        {
            setTimeout(function(){
                $("input[name=password]")[0].focus();
            },10);
        }
    }
}

function setLoginName()
{
    // Restore remembered username
    var username;
    if ($("body").is(".dev"))
    	username = SSN.Launcher.getSetting("DevLogin");
    else
    	username = SSN.Launcher.getSetting("Login");
    if(!$("#login").is(":hidden"))
    {
        if((username)&&(username!='undefined')&&(username!=undefined)){
            $("input[name=login]").val(username);
            $("input[name=remember]")[0].checked=true;
            $('input[name=remember]').attr('checked', 'checked').change();
        }else{
            $("input[name=login]").val('');
            $("input[name=remember]")[0].checked=false;
            $('input[name=remember]').attr('checked', '').change();
        }
    }
    setLoginFocus();
}

$(function(){
    setup();
    AjaxTest();
});
